﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;

//namespace NetworkSimulator
//{
//    public class POOA : Routing   
//    {
//        public int k;

//        public int kcount;

//        //contain k shortest paths of each i-e pair
//        List<List<Path>> kShortestPaths = new List<List<Path>>();

//        //Contain x value
//        List<List<int>> xlist = new List<List<int>>();


//        public POOA()
//            : base()
//        {
//            k = offline_RRATE.k;
//            kcount = 0;
//        }

//        public Link getLink(int s, int d)
//        {
//            foreach (var node in map.Nodes)
//                if (node.Id == s)
//                    foreach (var link in node.Links)
//                    {
//                        if (d == link.Destination.Id)
//                        {
//                            return link;
//                        }
//                    }
//            return null;
//        }

//        public void OfflinePhase()
//        {
//            //Maxflow of all i-e pairs
//            double maxflow = 0;

//            List<Path> increasingFlow = new List<Path>();

//            kShortestPaths = offline_RRATE.kShortestPaths;
//            xlist = offline_RRATE.xlist;

//            //Compute total maxflow
//            foreach (var ie in ieList.IngressEgressList)
//                maxflow += FindMaxFlow(ie.Ingress, ie.Egress, increasingFlow);


//            //Compute subflow on a link
//            #region
//            //contain paths to increase flow 

//            foreach (var ie in ieList.IngressEgressList)
//            {
//                //go to each path
//                foreach (var path in increasingFlow)
//                    foreach (var pathlink in path.Links)
//                        foreach (var node in map.Nodes)
//                            foreach (var maplink in node.Links)
//                                if (maplink.Source.Id == pathlink.Source.Id && maplink.Destination.Id == pathlink.Destination.Id)
//                                    maplink.Cost += path.cost;
//            }

//            //Criticality
//            foreach (var node in map.Nodes)
//                foreach (var link in node.Links)
//                    link.Cost = link.Cost / maxflow;
//            #endregion
//        }
    
//        public override Path getPath(Request req)
//        {
//            //Online phase
//            Path result = new Path();

//            //Get index of i-e
//            int p = 0;
//            foreach (var pair in ieList.IngressEgressList)
//            {
//                if (pair.Ingress.Id == req.Source && pair.Egress.Id == req.Destination) break;
//                else p++;
//            }


//            #region Learning stage
//            if (kcount < k)
//            {
//                Console.WriteLine("Learning:");
//                //Calculate Cost of each path
//                foreach (var path in kShortestPaths[p])
//                {
//                    double costtmp = 0;
//                    foreach (var link in path.Links)
//                        foreach (var node in map.Nodes)
//                            foreach (var maplink in node.Links)
//                                if (link.Source.Id == maplink.Source.Id && link.Destination.Id == maplink.Destination.Id)
//                                {
//                                    costtmp += maplink.Cost/maplink.ResidualBandwidth;
//                                }

//                    path.cost = costtmp;
//                }

//                //Flag to count how many times paths change order
//                bool flag = true;

//                //Sort paths in increasing order of cost
//                Path p_tmp = new Path();
//                int x_tmp;

//                for (int i = 0; i < k - 1; i++)
//                    for (int j = i + 1; j < k; j++)
//                        if (kShortestPaths[p][i].cost > kShortestPaths[p][j].cost)
//                        {
//                            //Swap position of k paths
//                            p_tmp = kShortestPaths[p][i];
//                            kShortestPaths[p][i] = kShortestPaths[p][j];
//                            kShortestPaths[p][j] = p_tmp;

//                            //Swap position of x value
//                            x_tmp = xlist[p][i];
//                            xlist[p][i] = xlist[p][j];
//                            xlist[p][j] = x_tmp;

//                            flag = false;
//                        }

//                if (flag)
//                {
//                    kcount++;
//                }


//                //Choose suitable path
//                for (int i = 0; i < k; i++)
//                {
//                    Path tmp = new Path();

//                    foreach (var linkofpath in kShortestPaths[p][i].Links)
//                        foreach (var node in map.Nodes)
//                            foreach (var link in node.Links)
//                                if (link.Source == linkofpath.Source && link.Destination == linkofpath.Destination)
//                                {
//                                    tmp.Links.Add(link);
//                                }
//                    if (tmp.ResidualBandwidth >= req.Bandwidth)
//                    {
//                        xlist[p][i]++;
//                        result = tmp;
//                        break;
//                    }
//                }
//                Console.WriteLine(result.ResidualBandwidth);
//            }
//            #endregion

//            #region Post_learning stage
//            else
//            {
//                //Sort x-value
//                for (int i = 0; i < k - 1; i++)
//                    for (int j = i + 1; j < k; j++)
//                        //if (kShortestPaths[p][i].cost > kShortestPaths[p][j].cost)
//                        if (xlist[p][i] < xlist[p][j])
//                        {
//                            //Swap position of k paths
//                            Path p_tmp = kShortestPaths[p][i];
//                            kShortestPaths[p][i] = kShortestPaths[p][j];
//                            kShortestPaths[p][j] = p_tmp;

//                            //Swap position of x value
//                            int x_tmp = xlist[p][i];
//                            xlist[p][i] = xlist[p][j];
//                            xlist[p][j] = x_tmp;
//                        }

//                //Choose suitable path
//                for (int i = 0; i < k; i++)
//                {
//                    Path tmp = new Path();
                 
//                    foreach(var linkofpath in kShortestPaths[p][i].Links)
//                            foreach (var node  in map.Nodes)
//                                foreach (var link in node.Links)
//                                    if (link.Source == linkofpath.Source && link.Destination == linkofpath.Destination)
//                                        tmp.Links.Add(link);
                    
//                    if (tmp.ResidualBandwidth >= req.Bandwidth)
//                    {
//                        xlist[p][i]++;
//                        result = tmp;
//                        break;
//                    }
//                }

//            }

//            #endregion

//            offline_RRATE.kShortestPaths = kShortestPaths;
//            offline_RRATE.xlist = xlist;

//            return result;
//        }

//    }
//}
